use std::collections::HashSet;
use chrono::{DateTime, Local};
use serde_derive::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use crate::db::pojo::pojo::{ImDepartment, ImDepartmentStatus};
use crate::business::websocket::dto::json_serialize::{date_time_serde, date_time_serde_null};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DepartmentInfoListReq {

    #[serde(rename = "startOrgCode")]
    pub start_org_code: Option<String>,

    #[serde(rename = "pageSize")]
    pub page_size: usize,

    #[serde(rename = "startDate", with = "date_time_serde_null")]
    pub start_date: Option<DateTime<Local>>,

    #[serde(rename = "isLatestChange")]
    pub is_latest_changed: bool,


    #[serde(rename = "createDateTime", with = "date_time_serde")]
    pub create_date_time: DateTime<Local>,

    #[serde(rename = "localSeq")]
    pub local_seq: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DepartmentInfoItemList {

    #[serde(rename = "departmentInfoItemList")]
    pub department_info_item_list: Vec<DepartmentInfoItem>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DepartmentInfoItem {

    #[serde(rename = "orgCode")]
    pub org_code: String,

    #[serde(rename = "departmentName")]
    pub department_name: String,

    #[serde(rename = "parentCode")]
    pub parent_code: Option<String>,
    pub des: Option<String>,

    #[serde(rename = "managerUserId")]
    pub manager_user_id: Option<String>,

    #[serde(rename = "otherManagerUserIdList")]
    pub other_manager_user_id_list: Option<HashSet<String>>,
    pub status: EnableType,
}

#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, PartialEq)]
#[repr(u8)]
pub enum EnableType {

    Enable = 1,
    Disable = 2,
}






impl Into<ImDepartment> for DepartmentInfoItem {
    fn into(self) -> ImDepartment {
        ImDepartment {
            id: None,
            current_user_id: "".to_string(),
            code: self.org_code,
            name: self.department_name,
            description: self.des,
            parent_code: self.parent_code,
            manager_user_id: self.manager_user_id,
            other_manager_user_id: self.other_manager_user_id_list,
            other_manager_user_ids: None,
            status: self.status.into(),
            create_date_time: Local::now(),
            update_date_time: Local::now(),
            ext1: None,
            ext2: None,
        }
    }
}

impl From<EnableType> for ImDepartmentStatus {
    fn from(value: EnableType) -> Self {
        match value {
            EnableType::Enable => {ImDepartmentStatus::Enable}
            EnableType::Disable => {ImDepartmentStatus::Disable }
        }
    }
}